#include <util.h>


#include <tiros/tiros.h>

/* To print out time */
#include <tiros/tr_util.h>

/* Example to show sleeping */
  


#define STKSIZE     (TIROS_MIN_CTXT_SZ + 64)
#define NUM_TASKS	     4


/* Stacks for each of our tasks */
osword_t task_stack[NUM_TASKS][STKSIZE];


void print_status(unsigned int secs)
{
	tid_t myid;
	myid = os_self_tid();
	puthexchar(myid);
	putstring("\twoke up: sleeping for ");
	puthexchar(secs);
	putstring(" seconds\n");
	
}

void idle_task(void *dummy)
{
	while(1) {
		putstring("Idle Task\n");
		delayms(10000);
	}
}

void task(void* dummy)
{
	unsigned int myid, mysleepsecs;
	trtime_t wake_time, curr_time, sleep_time;
	trtime_t meas_time;

	myid = (unsigned int) dummy;
	mysleepsecs = myid*4+2;


	/* Initial sleep for 5 secs */
	secs_to_trtime(5, &sleep_time);

	putstring("Task : "); puthexchar(myid); putchar(' ');

	if (myid == 2) { // This task will use relative time	
		putstring("sleeping for 5 secs\n");
		os_wake_at(&sleep_time, O_RELATIVE_TIME);
	} else {
		os_time_get(&curr_time);
		time_add(&sleep_time, &curr_time, &wake_time);
		putstring("At time: "); print_trtime(&curr_time);
		putstring(" calling wake at :"); print_trtime(&wake_time);
		putchar('\n');
		os_wake_at(&wake_time, 0);
	}

		
	secs_to_trtime(mysleepsecs, &sleep_time);
	

	while(1) {
		/* Sleeping for mysleepsecs seconds */

		print_status(mysleepsecs);
		if (myid == 2) { // This task will use relative time	
			os_wake_at(&sleep_time, O_RELATIVE_TIME);
		} else {
			os_time_get(&curr_time);
			time_add(&sleep_time, &curr_time, &wake_time);
			os_wake_at(&wake_time, 0);
			os_time_get(&meas_time);
			putstring("id:"); puthexchar(myid);
			putstring("\treq_time:");
			print_trtime(&wake_time);
			putstring("\tmeas_time:"); print_trtime(&meas_time);
			time_sub(&meas_time, &wake_time, &meas_time);
			putstring("\tresp_time:"); print_trtime(&meas_time);
			putchar('\n');
		}

	}	
}



void platform_init(void);
int main(void) 
{
	int i;
	tid_t tasks[NUM_TASKS];
	platform_init();


	// --------------------------------------------------
	os_init();


	for (i=0; i< NUM_TASKS-1; i++) 
		tasks[i] = os_task_create(task, (osptr_t)i,
			       task_stack[i], STKSIZE, i); 

	tasks[NUM_TASKS-1] = os_task_create(idle_task, (osptr_t)0,
			       task_stack[i], STKSIZE, i); 
	os_start();

	while (1);
}

